#include "CarMonitor.h"
#include "globalDef.h"
#include "string.h"
#include "L610.h"
#include "algorithm.h"
#include "CANProcess.h"
#include "adc_hw.h"
#include "paraTable.h"
#include "L610_hw.h"
#include "IAP.h"
#include "tim_hw.h"
#include "voldet.h"
#if def_EngineStart
#include "EngineStart.h"
#endif
#include "storeCarInf.h"

extern u8 u8throttle_open(void);
extern u8 u8air_condition(void);
extern u8 u8air_fan(void);
extern u8 u8air_fan_level(void);
extern uint8_t   car_key[12];		
uint8_t car_key_app[12] = {0};
extern void reInitPeripheral(void);
extern void goDeepSleep(void);
extern void clearRebootL610Sec(void);
//extern DATAFLOW DataFlow[];
extern u16 getDataFlowLen(void);
//extern DTCSAVEDATA DTCSaveData[];
extern u16 getDTCSaveDataLen(void);

CarMonitor_typedef	tagCarMon;
extern vehicle_state_updata tagCarS;
extern Health_Set INSP;//  保养信息
extern snwrv_data_msg_t snwrv_data_msg;
GLBUS_bmsg GLBUS_bmsg_date;
uint8_t bms_tim = 0;//桂林电池
#if( ADAS_COM_FUNCTION_DEF ==1 )
#define ADAS_INFOR_LEN	( 360 )
uint8_t adas_send_infor_buf[ADAS_INFOR_LEN];
#endif

#if( MCU_SAVE_DATA_ENABLE == 0 )
uint8_t mcu_save_data_st;

void mcu_save_data_st_set( uint8_t st )
{
	mcu_save_data_st = st;
}

uint8_t mcu_save_data_st_get( void )
{
	return mcu_save_data_st;
}

void mcu_form_cpu_data_request( void )
{
	static uint16_t new_time = 0, old_time = 0;
	uint8_t sdata[10] = { 0 },idx = 0;

	if( mcu_save_data_st == 0 ) 
	{
		new_time = get1msCounter();
		if(getTim1MsElaps(new_time , old_time) > _MS(1000))
		{
			sdata[idx++] = 0XEF;	//车辆状态字
			sdata[idx++] = 0;		//数据长度
			sdata[idx++] = 0;
			send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
			old_time = get1msCounter();
		}
	}
}

void mcu_form_cpu_data_handle( uint8_t *data, uint16_t len )
{
	uint32_t tp_data = 0;
	
	if( len == 64 )
	{
		tagCarS.doors_status = data[0];		/*车门状态*/
		tagCarS.lights_status = data[1];	/*灯光状态*/
		tagCarS.win_status = data[2];		/*车窗状态*/
		tagCarS.lock = data[3];				/*车锁状态*/
		tagCarS.brake_gear = data[4];		/*刹车状态*/
		tagCarS.Ignition_status = data[5];	/*ACC状态*/
		tagCarS.Charge_status = data[6];	/*充电状态*/
		tagCarS.other_status = data[7];		/*其他状态*/
		tagCarS.speed = hex2CombineOne(&data[8]);	/*速度*/
		//tagCarS.bat_vol = hex4CombineOne(&data[10]);	/*电量*/
		tagCarS.Odo = hex4CombineOne(&data[14]);		/*里程*/
		tagCarS.Oil = hex2CombineOne(&data[18]);		/*油量*/
		tagCarS.Electricity = hex2CombineOne(&data[20]);		/*电量*/
		tagCarS.Endurance_mileage = hex2CombineOne(&data[22]);	/*剩余电量*/
		//tagCarS.relay_sta = data[24]&0x01;			/*继电器状态*/
		/*胎压位置48，4个字节*/
		tp_data =  hex4CombineOne( &data[25] );			/*胎压*/
		tagCarS.lf_TP = ( uint8_t )(( tp_data & 0xFF000000 ) >> 24);	//左前轮胎压值
		tagCarS.rf_TP = ( uint8_t )(( tp_data & 0x00FF0000 ) >> 16);	//右前轮胎压值
		tagCarS.lr_TP = ( uint8_t )(( tp_data & 0x0000FF00 ) >> 8);	//左后轮胎压值
		tagCarS.rr_TP = ( uint8_t )( tp_data & 0x000000FF );			//右后轮胎压值
		/*胎温位置56，4个字节*/	
		tp_data =  hex4CombineOne( &data[29] );			/*胎温*/
		tagCarS.lf_T = ( uint8_t )(( tp_data & 0xFF000000 ) >> 24);	//左前轮胎温度，房车项目 清水状态上报 复用
		tagCarS.rf_T = ( uint8_t )(( tp_data & 0x00FF0000 ) >> 16);	//右前轮胎温度，房车项目 灰水状态上报 复用
		tagCarS.lr_T = ( uint8_t )(( tp_data & 0x0000FF00 ) >> 8);		//左后轮胎温度，房车项目 大电平电压高字节
		tagCarS.rr_T = ( uint8_t )( tp_data & 0x000000FF );			//右后轮胎温度，房车项目 大电平电压低字节
		tagCarS.TPMSRst = data[33];						//胎压标志是否有效
		//tagCarS.vehicle_type = data[34];				//填充车辆类型
		/*房车项目52，一个字节*/
		//tagCarS.back_T = data[35]; 					/*房车项目，黑水水位标志*/
		mcu_save_data_st_set( 1 );
	}
}

#endif

#if( ADAS_COM_FUNCTION_DEF ==1 )
/**
 * @brief 固定间隔发送数据
 * 
 */
void adas_send_info_function( void )
{
	static uint16_t new_time = 0, old_time = 0, adas_time = 0;
	uint8_t adas_buf[32] = { 0 }, idx = 0;
	uint16_t position = 0;
	/*检测发动机状态运行是否正常*/
	if(( tagCarS.Ignition_status & 0x08 ) == 0x08 )
	{
		new_time = get1msCounter();
		if(getTim1MsElaps(new_time , old_time) > _MS(200))
		{
			/*发送本地ADAS数据，通过RS232接口进行数据发送*****************************************/
			//km/h小计里程车速
			u16toHex2( u16AutoSpeed(), &adas_buf[idx]);
			idx += 2;
			//油门踏板的位置
			adas_buf[idx] = tagCarS.OilRst;
			idx += 1;
			//挡位状态 
			adas_buf[idx] = ( u8AutoGearSt() & 0x3F );
			//左转赋值、右转赋值
			if(!(tagCarS.lights_status&0x20))//双闪关闭 再判定转向 只传左闪 或 又闪
			{
				if(tagCarS.lights_status&0x08)     
				{
					adas_buf[idx]|=0x40;
				}
				else if(tagCarS.lights_status&0x10)
				{
					adas_buf[idx]|=0x80;
				}	
			} 
			idx += 1;
			//方向盘角度
			u16toHex2( tagCarS.Wheel_Deg, &adas_buf[idx]);
			idx += 2;
//			/*车辆转向灯状态*/
//			adas_buf[idx] = tagCarS.lights_status;
//			idx += 1;
			send_general_package_to_uart(0x2101, adas_buf, idx, 0, 0, 2);
			/*发送远程ADAS数据，发送到MPU进行网络数据发送。数据采样周期1S*************************************/
			adas_time++;
			if( adas_time >= 5 )	
			{
				adas_time = 0;
				position = adas_send_infor_buf[0] * 6 + 1;
				/*车辆速度两个字节表示。0x00,0x50表示8.0Km/H*/
				u16toHex2( u16AutoSpeed(), &adas_send_infor_buf[position] );
				position += 2;
				/*油门踏板角度单字节表示。0x20表示油门踏板32度。0xFF表示无效值。*/
				adas_send_infor_buf[position] = tagCarS.OilRst;
				position += 1;
				/*刹车踏板角度单字节表示。0x20表示油门踏板32度。0xFF表示无效值。*/
				if( ( tagCarS.brake_gear & 0x02 ) == 0x02 )
				{
					adas_send_infor_buf[position] = 101;
				}
				else
				{
					adas_send_infor_buf[position] = 0;
				}
				position += 1;
				/*方向盘角度两个字节，单位0.1度*/
				u16toHex2( tagCarS.Wheel_Deg, &adas_send_infor_buf[position] );
				position += 2;
				adas_send_infor_buf[0]++;
				if( adas_send_infor_buf[0] >= 50 )
				{
					send_general_package_to_uart(0x2087, adas_send_infor_buf, (adas_send_infor_buf[0] * 6 + 1), 0, 0, 1);
					memset( (uint8_t *)adas_send_infor_buf, 0x00, ADAS_INFOR_LEN );
				}
			}
			old_time = get1msCounter();
		}
	}
	else
	{
		old_time = get1msCounter();
		adas_time = 0;
		if( adas_send_infor_buf[0] != 0 )
		{
			send_general_package_to_uart(0x2087, adas_send_infor_buf, (adas_send_infor_buf[0] * 6 + 1), 0, 0, 1);
			memset( (uint8_t *)adas_send_infor_buf, 0x00, ADAS_INFOR_LEN );
		}
	}
}

/**
 * @brief ADAS查询车辆信息
 * 
 * @param data 读取数据目标地址。
 * @param cmd 查询命令
 * @return uint8_t 返回数据长度
 */
uint8_t adas_search_info_function( uint8_t *data, uint8_t cmd )
{
	uint8_t size = 0;

	if( data == NULL )
	{
		return 0;
	}
	if( cmd == 0x80 )		/*查询版本号*/
	{
		data[0] = 0x80;
		data[1] = 9;
		memcpy( (uint8_t *)&data[2], (uint8_t *)_def_verson, 9 );
		size = 11;
	}
	else if( cmd == 0x81 )	/*查询车辆VIN*/
	{
		data[0] = 0x81;
		data[1] = 17;
		memcpy( (uint8_t *)&data[2], (uint8_t *)tagCarS.vehicleVIN, 17 );
		size = 19;
	}
	
	return size;
}
#endif
//发送SEED数据
void vehicle_safety_seed_report( uint8_t *data )
{
	uint16_t idx;
	uint8_t sdata[200] = { 0 };
	
	idx = 0;
	sdata[idx++] = _def_verson[2];		//车辆类型
	sdata[idx++] = _def_verson[3];		//车辆车系
	sdata[idx++] = data[0];
	memcpy( (uint8_t *)&sdata[idx], (uint8_t *)&data[1], data[0] );
	idx += data[0];
	
	send_general_package_to_uart(0x2084, sdata, idx, 0, 0, 1);
}

/*汽车胎压值获取*/
uint32_t auto_tire_pressure_get( void )
{
	return ( (tagCarS.lf_TP<<24) | (tagCarS.rf_TP<<16) | (tagCarS.lr_TP<<8) | (tagCarS.rr_TP ) );
}

/*汽车胎温值获取*/
uint32_t auto_tire_temp_get( void )
{
	return ( (tagCarS.lf_T<<24) | (tagCarS.rf_T<<16) | (tagCarS.lr_T<<8) | (tagCarS.rr_T ) );
}

//保存平台下发 保养信息
uint32_t set_car_Health(uint8_t* da , uint8_t len)
{
	if ( len == 19 )
	{
		INSP.newdatast = 1;
		//保养时间 -BCD码
		memcpy( (uint8_t *)INSP.Rtc_BCD, (uint8_t *)da, 6 );
		//保存保养里程 - 大保养
		INSP.Health_Odo = hex4CombineOne(&da[6]);
		//保存保养时间 - 大保养
		INSP.Health_Tim = hex2CombineOne(&da[10]);
		//保存保养里程 - 小保养
		INSP.Health_Odo_l = hex4CombineOne(&da[12]);
		//保存保养时间 - 小保养 
		INSP.Health_Tim_l = hex2CombineOne(&da[16]);
		//保存保养机油百分比
		INSP.Oillife_Per = da[18];
		return 1;
	}
	
	return 0;
}

//上传车辆保养状态
void reported_car_Health(void)
{
	uint16_t idx;
	uint8_t sdata[200] = { 0 };
	uint16_t subContentLen = 0;

	idx = 0;
	//content
	sdata[idx++] = 0XB1;		//车辆状态字
	/*数据长度，固定为 35X4 */
	subContentLen = 13;
	//写入长度
	sdata[idx++] = subContentLen / 0x100;
	sdata[idx++] = subContentLen % 0x100;

	// tagCarS.Health_Odo = 0xFFFFFFFF;
	// tagCarS.Health_Tim = 0xFFFF;
	// tagCarS.Health_Odo_l = 0xFFFFFFFF;
	// tagCarS.Health_Tim_l = 0xFFFF;
	// tagCarS.Oillife_Per = 0xFF;
	

	/*拷贝保养里程数据，数据长度 4 */
	u32toHex4( tagCarS.Health_Odo, &sdata[idx]);
	idx += 4;
	/*拷贝保养时间，数据长度 2 */
	u16toHex2( tagCarS.Health_Tim , &sdata[idx] );
	idx += 2;
	/*拷贝小保养里程数据，数据长度4*/
	u32toHex4( tagCarS.Health_Odo_l, &sdata[idx]);
	idx += 4;
	/*拷贝小保养时间，数据长度 2 */
	u16toHex2( tagCarS.Health_Tim_l , &sdata[idx] );
	idx += 2;
	/*拷贝机油百分比，数据长度 1 */
	sdata[idx]=tagCarS.Oillife_Per;
	idx += 1;
	
	/*发送数据*/
	send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
}

//桂林公交使用，上传电池信息
void reported_car_bms(void)
{
	uint16_t idx;
	uint8_t sdata[200] = { 0 };
	uint16_t subContentLen = 0;
	idx = 0;
	//content
	sdata[idx++] = 0XB2;		//车辆状态字
	/*数据长度，固定为  */
	subContentLen = 80;
	//写入长度
	sdata[idx++] = subContentLen / 0x100;
	sdata[idx++] = subContentLen % 0x100;

	memcpy(&sdata[idx],GLBUS_bmsg_date.monitor,3);
	idx += 3;
	sdata[idx]=GLBUS_bmsg_date.cell_soh;
	idx += 1;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms2_1,8);
	idx += 8;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms4,8);
	idx += 8;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms5,8);
	idx += 8;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms5_1,8);
	idx += 8;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms5_2,8);
	idx += 8;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms5_3,8);
	idx += 8;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms5_4,8);
	idx += 8;
	sdata[idx]=GLBUS_bmsg_date.bms5_5;
	idx += 1;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms6,4);
	idx += 4;
	memcpy(&sdata[idx],GLBUS_bmsg_date.bms7,8);
	idx += 8;
	
	send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
	GLBUS_bmsg_date.newdatast = 0;
	
}

/**
 * @brief 赛呐威房车 数据发送
 * 
 */
void snwrv_data_msg_send( void )
{
	uint16_t idx = 0;
	uint8_t  sdata[200] = { 0 };
	
	if( snwrv_data_msg.project_id != 0x00 )
	{	
		sdata[0] = 0;									/*数据包长度，开始时默认为0*/
		idx += 1;
		sdata[idx] = snwrv_data_msg.project_id;			/*项目标识*/
		idx += 1;
		sdata[idx] = snwrv_data_msg.clear_water_st;		/*清水状态*/
		idx += 1;
		sdata[idx] = snwrv_data_msg.gray_water_st;		/*灰水状态*/
		idx += 1;
		sdata[idx] = snwrv_data_msg.black_water_st;		/*黑水状态*/
		idx += 1;
		u16toHex2( snwrv_data_msg.room_st, &sdata[idx] );			/*大电平上电状态*/
		idx += 2;
		u16toHex2( snwrv_data_msg.total_voltage, &sdata[idx] );		/*总电压*/
		idx += 2;
		u16toHex2( snwrv_data_msg.total_current, &sdata[idx] );		/*总电流*/
		idx += 2;
		u16toHex2( snwrv_data_msg.surplus_capacity, &sdata[idx] );	/*剩余容量*/
		idx += 2;
		u16toHex2( snwrv_data_msg.full_capacity, &sdata[idx] );		/*充满容量*/
		idx += 2;
		u32toHex4( snwrv_data_msg.battery_state, &sdata[idx] );		/*电池组均衡状态*/
		idx += 4;
		u16toHex2( snwrv_data_msg.protection_mark, &sdata[idx] );	/*保护标识*/
		idx += 2;
		
		/*发送数据*/
		sdata[0] = idx - 1; /*结构体数据长度*/
		send_general_package_to_uart(0x2086, sdata, idx, 0, 0, 1);
		snwrv_data_msg.project_id = 0;								/*发送数据结束后清空项目标识*/
	}
}

void initCarMonitor(void)
{
	memset(&tagCarMon, 0, sizeof(CarMonitor_typedef));
	tagCarMon.askInputDlySec = 0xFF00; //开机先主动发1次查询状态

	//初始化采样电源电压的ADC
	adc_config(0);
	tagCarMon.PowerADCAvg = getAdcValue(0);	//先采样一次，方便其他接口使用
	/*房车项目车身数据初始化*/
	memset( (uint8_t *)&snwrv_data_msg, 0x00, sizeof( snwrv_data_msg_t ) );
	/*ADAS数据缓存初始化*/
#if( ADAS_COM_FUNCTION_DEF ==1 )
	memset( (uint8_t *)adas_send_infor_buf, 0x00, ADAS_INFOR_LEN );
#endif
#if( MCU_SAVE_DATA_ENABLE == 0 )
	mcu_save_data_st = 0;


#endif
}

/*
获取外部IO输入：1高电平，0低电平
ADC输入值：单位mV

如果返回0xFFFF代表未解析到串口数据，
如果主动查询但L610未返回，也会返回0xFFFF

输入参数说明
0x00：IN0，对应对外16Pin.9
0x01: IN1,对应对外18Pin.5
0x02: IN2,对应对外18Pin.6
0x03: IN3,对应对外18Pin.8
0x04: IN4,对应对外18Pin.15
0x05: IN5,对应对外18Pin.16
0x06: IN5,对应对外18Pin.13
0x07: 预留
0x08：InputA，对应对外16Pin.8
0x09：InputB，对应对外16Pin.7
0x20:	AD5，对应对外18Pin.2
0x21:	AD6，对应对外18Pin.3
0x22:	AD7，对应对外18Pin.4

mustNew = 1代表必须使用查询收到应答的数据，0代表可以使用历史数据
*/
uint16_t getL610IO_Input(uint8_t inNum, uint8_t mustNew)
{
	uint16_t reDa;
	
	if ((tagCarMon.InputSta == 0x00) && (mustNew))
	{
		return 0xFFFF;
	}
	
	switch(inNum)
	{
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
			reDa = (tagCarMon.IN0_7>>inNum) & 0x01;
		break;
		case 0x08:
			reDa = (tagCarMon.InputAB) & 0x0001;
		break;
		case 0x09:
			reDa = (tagCarMon.InputAB>>1) & 0x0001;
		break;
		case 0x20:
			reDa = tagCarMon.AD5;
		break;
		case 0x21:
			reDa = tagCarMon.AD6;
		break;
		case 0x22:
			reDa = tagCarMon.AD7;
		break;
		default:
			reDa = 0xFFFF;
			break;
	}
	
	return reDa;
}

//解析L610发过来的
void parseCarIO(uint8_t * pDa, uint16_t len)
{
	tagCarMon.InputSta = 0x01;	//代表收到过后台下发的实时数据了
	tagCarMon.askInputDlySec = 0; //清除查询间隔
	
	if (len >= 9)
	{
		tagCarMon.IN0_7 = pDa[0];
		tagCarMon.InputAB = pDa[1] * 0x100 + pDa[2];
		tagCarMon.AD5 = pDa[3] * 0x100 + pDa[4];
		tagCarMon.AD6 = pDa[5] * 0x100 + pDa[6];
		tagCarMon.AD7 = pDa[7] * 0x100 + pDa[8];
	}
	
}

//返回0代表操作成功，返回其他值代表失败
uint32_t askCarInf(uint8_t * pDa, uint16_t len)
{
	uint8_t checkCmd;
	uint16_t code = 0;
	if (len < 1)
	{
		return 1;
	}
	
	checkCmd = pDa[0];
	
	switch(checkCmd)
	{
		case 0xAE:	//获取电车数据流
			//PushDataFlowToL610();
			SetCheckAESta(1);
			break;
		
		case 0xAF:	//获取电车故障码
			//PushDTCSaveDataToL610();
			SetCheckAFSta(1);
			break;
		
		case 0x02:	//PID，内容同A7
			SetCheckPIDSta(1);
			break;
		
		case 0x03:	//故障列表，内容同A5
			SetCheckErrListSta(1);
			break;
		
		case 0x04:	//维修数据，内容同AB
			SetCheckMendSta(1);
			break;
		
		case 0x01:
			answerCarInf();		//大部分车身状态参数
			answerCarInf_VIN();	//VIN 
			break;
		
		case 0xA1:
			answerCarInf_VIN();	//VIN
			break;
		
		case 0xA4:	//里程相关
			answerCarInf_mile();
			break;
		
		case 0xA5:	//故障列表
			answerCarInf_errorList(0xA5);
			break;
		
		case 0xA7:	//标准PID信息列表
			answerCarInf_PIDList(0xA7);
			break;
		
		case 0xA8:
			answerGDVersion(0xA8);	//产品序列号
			break;
		case 0xA9:
			answerGDVersion(0xA9);	//回复硬件版本号
			break;
		case 0xAA:
			answerGDVersion(0xAA);	//回复软件版本号
			break;
		case 0xAB:
			answerCarInf_mend(0xAB);
			break;
		
		case 0xB0:
			answerCarInf_EnableList();
			break;
		case 0xCC:
			answerpkekey();
			break;
		case 0xCD:
			code = (pDa[1]<<8)|pDa[2];
			answerstartpower(code);
			break;
		case 0xEF:
		#if( MCU_SAVE_DATA_ENABLE == 0 )
			mcu_form_cpu_data_handle( (uint8_t *)&pDa[3], ((pDa[1]<<8)|pDa[2]) );
		#endif
			break;
		default:
			return 2;

	}
	
	return 0;
	
}



uint32_t answerGDVersion(uint8_t type)
{
	uint16_t idx;
	uint8_t sdata[100];
	uint32_t txlen;

	//Message_ID
	idx = 0;
	memcpy(&sdata[idx], "\x20\x17", 2);
	idx += 2;

	//Message_Property,afterward
	idx += 2;

	//Terminal_Num
	get_para_car_id(&sdata[idx]);
	idx += 6;

	//Message_Serial_Number
	fill_serial_num(&sdata[idx]);
	idx += 2;

	//content
	switch(type)
	{
		case 0xA8:	//产品序列号
			sdata[idx++] = type;	//车辆状态字
		
			sdata[idx++] = 0x00;	//状态内容长度
			sdata[idx++] = 0x0C;	//12字节长度的序列号
		
			u32toHex4(*(uint32_t *)(0x1FFFF7F0), &sdata[idx]);
			idx += 4;
		
			u32toHex4(*(uint32_t *)(0x1FFFF7EC), &sdata[idx]);
			idx += 4;
		
			u32toHex4(*(uint32_t *)(0x1FFFF7E8), &sdata[idx]);
			idx += 4;
			
			break;
		
		case 0xA9:	//硬件版本号
			sdata[idx++] = type;	//车辆状态字
	
			sdata[idx++] = 0x00;	//状态内容长度
			sdata[idx++] = 0x03;
	
			memcpy(&sdata[idx], _def_verson+6, 3);
			idx += 3;
			break;
		
		case 0xAA:	//软件版本号
			sdata[idx++] = type;	//车辆状态字
	
			sdata[idx++] = 0x00;	//状态内容长度
			sdata[idx++] = 0x06;
	
			memcpy(&sdata[idx], _def_verson, 6);
			idx += 6;
			break;
		
		default:
			return 1;
			//break;
	}
	

	//消息体属性
	txlen = idx + 1;
	if (txlen < 13)
	{
		txlen = 13;
	}
	sdata[2] = (uint8_t)((txlen - 13) >> 8);
	sdata[3] = (uint8_t)(txlen - 13);

	//校验
	sdata[idx] = get_chk_xor(sdata, idx);
	idx++;

	format_and_send_to_mcu(sdata, idx);
	
	return 0;
}



uint32_t answerCarInf_errorList(uint8_t da)
{
	uint16_t idx;
	uint8_t sdata[100];
	uint16_t subContentLen = 0;
	uint16_t	i;
	
	idx = 0;
	//content
	sdata[idx++] = da;	//车辆状态字
	
	subContentLen = u8GetDTCCount() * 4;
	if (subContentLen > 40) return 3;	//数组最长10个 * 4byte
	
	//写入长度
	sdata[idx++] = subContentLen / 0x100;
	sdata[idx++] = subContentLen % 0x100;
	
	//获取故障码数组,这种内存拷贝不严谨
	memcpy(&sdata[idx], u32GetDTCarray(), subContentLen);
	
	for(i=0;i<subContentLen;i+=4)
	{
		u32toHex4(*((u32*)&sdata[idx+i]), &sdata[idx+i]);
	}
	
	idx+= subContentLen;

	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
}

uint32_t answer_fault_code_information_send(uint8_t da)
{	
	uint16_t idx;
	uint8_t sdata[200] = { 0 };
	uint16_t subContentLen = 0;
	uint16_t i = 0;
	
	idx = 0;
	//content
	sdata[idx++] = da;		//车辆状态字
	/*数据长度，固定为 35X4 */
	subContentLen = 180;
	//写入长度
	sdata[idx++] = subContentLen / 0x100;
	sdata[idx++] = subContentLen % 0x100;
	/*拷贝通用故障列表，数据长度 15 */
	for( i = 0; i < 15; i ++ )
	{
		u32toHex4( tagCarS.DTCLIST[i], &sdata[idx]);
		idx += 4;
	}
	/*拷贝发动机故障码列表，数据长度 10 */
	for( i=0; i<10; i++ )
	{
		u32toHex4( tagCarS.EMSDTdCLT[i] , &sdata[idx] );
		idx += 4;
	}
	/*拷贝发动机故障列表，数据长度 10 */
	for( i=0; i<10; i++ )
	{
		u32toHex4( tagCarS.TCUDTCLT[i] , &sdata[idx] );
		idx += 4;
	}
	/*拷贝电源管理故障列表，数据长度10*/
	for( i=0; i<10; i++ )
	{
		u32toHex4( tagCarS.BMSDTCLT[i] , &sdata[idx] );
		idx += 4;
	}
	/*发送数据*/
	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
}

uint32_t answerCarInf_mend(uint8_t da)
{
	uint16_t idx;
	uint16_t carParaLen;	//用于车身参数长度计算
	uint8_t sdata[100];
	
	//content
	idx = 0;
	sdata[idx++] = da;	//车辆状态字
	
	//后期写入
	carParaLen = idx;
	//sdata[idx++] = 0x00;	//状态内容长度
	//sdata[idx++] = 0x00;	
	idx +=2;
	
	//静态电压
	u32toHex4(u32static_v(), &sdata[idx]);
	idx += 4;
	//启动电压
	u32toHex4(u32launch_v(), &sdata[idx]);
	idx += 4;
	//节气门信号电压
	u32toHex4(u32thr_s_v(), &sdata[idx]);
	idx += 4;
	//油门踏板位置传感器电压
	u32toHex4(u32pedal_s_v(), &sdata[idx]);
	idx += 4;
	//喷油脉宽
	u32toHex4(u32inject_p_w(), &sdata[idx]);
	idx += 4;
	
	//喷油量
	u32toHex4(u32inject_p_q(), &sdata[idx]);
	idx += 4;
	//喷油嘴时间
	u32toHex4(u32inject_p_t(), &sdata[idx]);
	idx += 4;
	
	//供油压力
	u32toHex4(u32oil_s_p(), &sdata[idx]);
	idx += 4;
	//进气压力
	u32toHex4(u32air_in_p(), &sdata[idx]);
	idx += 4;
	//进气温度
	u32toHex4(u32air_in_t(), &sdata[idx]);
	idx += 4;
	//水温
	u32toHex4(u32water_t(), &sdata[idx]);
	idx += 4;
	//前氧传感器电压
	u32toHex4(u32f_o_v(), &sdata[idx]);
	idx += 4;
	//后氧传感器电压
	u32toHex4(u32b_o_v(), &sdata[idx]);
	idx += 4;
	
	
	//后写入车身参数长度
	sdata[carParaLen] = (idx - 2 - carParaLen) / 0x100;
	sdata[carParaLen+1] = (idx - 2 - carParaLen)%0x100;


	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);

}
uint32_t answerCarInf_EnableList(void)
{

	uint16_t idx;
	uint8_t sdata[100];
	
	//content
	idx = 0;
	sdata[idx++] = 0xB0;	//车辆状态字
	
	sdata[idx++] = 0x00;	//状态内容长度
	sdata[idx++] = 0x0B;
	
	//使能表
	memcpy(&sdata[idx], (uint8_t*)u8GetFuncAble(), 11);
	idx += 11;
	
	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
}
		
uint32_t answerCarInf_PIDList(uint8_t da)
{
	uint16_t idx;
	uint8_t sdata[800];
	uint16_t PIDcnt = 0;
	uint16_t subContentLen = 0;
	
	//content
	idx = 0;
	sdata[idx++] = da;	//车辆状态字
	

	//写入长度
	//sdata[1] = subContentLen / 0x100;
	//sdata[2] = subContentLen % 0x100;
	
	idx = 3;
	PIDcnt = getPIDList(&sdata[idx]);
	subContentLen = PIDcnt*6;
	idx += PIDcnt*6;	//每个PID占用6字节

	sdata[1] = subContentLen / 0x100;
	sdata[2] = subContentLen % 0x100;
	
	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
	
	
}

uint32_t answerCarInf_mile(void)
{
	uint16_t idx, carParaLen;
	uint8_t sdata[200];
	
	//content
	idx = 0;
	sdata[idx++] = 0xA4;	//车辆状态字
	
	//后期写入
	carParaLen = idx;
	//sdata[idx++] = 0x00;	//状态内容长度
	//sdata[idx++] = 0x00;	
	idx +=2;
	
	//要求读取的内容
	//里程
	u32toHex4(u32AutoOdo(), &sdata[idx]);
	idx += 4;
	//油量
	u16toHex2(u16AutoFuel(), &sdata[idx]);
	idx += 2;
	//续航
	u16toHex2(u16SocForMile(), &sdata[idx]);
	idx += 2;
	//小计里程
	u32toHex4(u32TripMile(), &sdata[idx]);
	idx += 4;
	//km/h小计里程车速
	u16toHex2(u16TripSpeed(), &sdata[idx]);
	idx += 2;
	//L/100Km小计里程平均油耗
	u32toHex4(u32TripAvgOilCsp(), &sdata[idx]);
	idx += 4;
	//min小计里程时间
	u32toHex4(u32TripTime(), &sdata[idx]);
	idx += 4;
	//km自启动里程
	u32toHex4(u32StartupMile(), &sdata[idx]);
	idx += 4;
	//km/h自启动后车速
	u16toHex2(u16StartupSpeed(), &sdata[idx]);
	idx += 2;
	//L/100Km自启动后平均油耗
	u32toHex4(u32StartupAvgOilCsp(), &sdata[idx]);
	idx += 4;
	//min自启动后时间
	u32toHex4(u32StartupTime(), &sdata[idx]);
	idx += 4;


	//后写入车身参数长度
	sdata[carParaLen] = (idx - 2 - carParaLen) / 0x100;
	sdata[carParaLen+1] = (idx - 2 - carParaLen)%0x100;
	
	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
	
}


uint32_t answerCarInf_VIN(void)
{
	uint16_t idx;
	uint8_t sdata[100];
	
	//content
	idx = 0;
	sdata[idx++] = 0xA1;	//车辆状态字
	
	sdata[idx++] = 0x00;	//状态内容长度
	sdata[idx++] = 0x11;
	
	//VIN
	if(u8GetVINCarry() != 0)
	{
		memcpy(&sdata[idx], (uint8_t*)u8GetVINCarry(), 17);
		idx += 17;
		

		return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
	}
	else
		return 0;
}

uint32_t answerpkekey(void)
{
	uint16_t idx;
	uint8_t sdata[100];
	
	//content
	idx = 0;

	//u32toHex4(1, &sdata[idx]);
	memcpy(&sdata[idx], car_key_app, 4);  //id
	idx += 4;
	//memcpy(&sdata[idx], &car_key_app[4], 4);//sn
	//u32toHex4(2, &sdata[idx]);
	//idx += 4;
	sdata[idx++] = ((car_key_app[4]>>4)&0x0f); //sn
	sdata[idx++] = ((car_key_app[5]>>4)|((car_key_app[4]&0x0f)<<4));
	sdata[idx++] = ((car_key_app[6]>>4)|((car_key_app[5]&0x0f)<<4));
	sdata[idx++] = ((car_key_app[7]>>4)|((car_key_app[6]&0x0f)<<4));
	
	//memcpy(&sdata[idx], &car_key_app[4], 4);//code
	sdata[idx++] = (car_key_app[7]&0x00);
	sdata[idx++] = (car_key_app[7]&0x00);
	sdata[idx++] = (car_key_app[7]&0x00);
	sdata[idx++] = (car_key_app[7]&0x0F);
	//u32toHex4(3, &sdata[idx]);
	//idx += 4;
	
	return send_general_package_to_uart(0x207D, sdata, idx, 0, 0, 1);
}
uint32_t answerstartpower(uint16_t code)
{
	uint16_t idx;
	uint8_t sdata[100];
	
	//content
	idx = 0;
	#if def_EngineStart
	u16toHex2(tagEngS.startp_sn, &sdata[idx]);
	#endif
	idx += 2;
	#if def_EngineStart
	u16toHex2(tagEngS.startp_cmd, &sdata[idx]);
	#endif
	idx += 2;
	if(code == 0xffff)
	{
		sdata[idx++] = 0x00;	
	}
	else
	{
		sdata[idx++] = 0x01;	
		u16toHex2(code, &sdata[idx]);
		idx += 2;
	}
	
	return send_general_package_to_uart(0x20A6, sdata, idx, 0, 0, 1);
}
//调用串口给L610发查询IO状态报文
//正常情况不主动查询，要求L610发现IO变化主动上报
//对于ADC数值，应该是使用前马上查询，不过对于变化较快的电压值仍会采样偏差
uint32_t askL610CarIOStatues(void)
{
	uint16_t idx;
	uint8_t sdata[100];
	uint32_t txlen;

	//Message_ID
	idx = 0;
	memcpy(&sdata[idx], "\x20\x11", 2);
	idx += 2;

	//Message_Property,afterward
	idx += 2;

	//Terminal_Num
	get_para_car_id(&sdata[idx]);
	idx += 6;

	//Message_Serial_Number
	fill_serial_num(&sdata[idx]);
	idx += 2;

	//content
	//空

	//消息体属性
	txlen = idx + 1;
	if (txlen < 13)
	{
		txlen = 13;
	}
	sdata[2] = (uint8_t)((txlen - 13) >> 8);
	sdata[3] = (uint8_t)(txlen - 13);

	//校验
	sdata[idx] = get_chk_xor(sdata, idx);
	idx++;

	format_and_send_to_mcu(sdata, idx);
	
	return 0;
}


//每秒被调用1次的函数
void carMonitorSecDeal(void)
{
	if (tagCarMon.askInputDlySec < 0xFFF0)
	{
		tagCarMon.askInputDlySec++;
	}
	
	//为了测试，每30秒查询1次IO状态
	if (tagCarMon.askInputDlySec > 180)
	{
		tagCarMon.askInputDlySec = 0;
		
		tagCarMon.InputSta = 0; //清历史数据
		//askL610CarIOStatues();
	}
	
}





void deal_active_push_msg(void)
{
	u8 needSend01 = 0;
	u8 needSendA1 = 0;
	//u8 needSendA4 = 0;
	//u8 needSendA5 = 0;
	//u8 needSendA7 = 0;
	//u8 needSendAB = 0;
	u8 needSendCC = 0;
	//u8 needSendDataFlow = 0;		//AE
	//u8 needSendAF = 0;		//AF
	
	static u8 needSendOthers = 0;
	u8 buf[600];
	static u32 secOld = 0;
	static u32 secCnt = 0;
	//每分钟都发送1次
	if (secOld != get1sCounter())
	{
		secOld = get1sCounter();
		secCnt++;
		if (secCnt > 60*60)
		{
			secCnt = 0;
			needSend01 = 1;
			needSendA1 = 1;
			//needSendA4 = 1;
			//needSendA5 = 1;
			//needSendA7 = 1;
			//needSendAB = 1;
			//needSendDataFlow = 1;
			//needSendAF = 1;
			//needSendOthers = 0;
		}
	}
	/////////////////////////////增加AF- 获取电?车故障码
	///////////////////////////////////////////////////////////  others
	if (needSendOthers != 0xA1)
	{
		needSendOthers = 0xA1;
//		answerGDVersion(0xA8);	//产品序列号
//		answerGDVersion(0xA9);	//回复硬件版本号
//		answerGDVersion(0xAA);	//回复软件版本号
//		answerCarInf_EnableList();	//使能位
	}
	if (memcmp(car_key_app, car_key, sizeof(car_key)) != 0)
	{
		memcpy(car_key_app, car_key, sizeof(car_key));
		needSendCC = 0xCC;
	}
	if (needSendCC == 0xCC)
	{
		buf[0] = 0xCC;
		askCarInf(buf, 1);
	}
	///////////////////////////////////////////////////////////  A1 VIN
	if (memcmp(u8GetVINCarry, tagCarMon.u8GetVINCarry, 17) != 0)
	{
		memcpy(tagCarMon.u8GetVINCarry, u8GetVINCarry, 17);
		needSendA1 = 0x01;
	}
	if (needSendA1 == 0x01)
	{
		buf[0] = 0xA1;
		askCarInf(buf, 1);
	}
	/////////////////////////////////////////////////////////// 一键启动
	#if def_EngineStart
	if(tagEngS.ErrorCode != 0)
	{
		buf[0] = 0xCD;
		buf[1] = tagEngS.ErrorCode>>8;
		buf[2] = tagEngS.ErrorCode&0xff;
		askCarInf(buf, 3);
		tagEngS.ErrorCode = 0;
	}
	#endif
#if( MCU_SAVE_DATA_ENABLE == 0 )
	if( mcu_save_data_st_get() == 0x00 )
	{
		return;
	}
#endif
	///////////////////////////////////////////////////////////  01
	//车门状态
	if (tagCarMon.u8AutoDoorSt != u8AutoDoorSt())
	{
		tagCarMon.u8AutoDoorSt = u8AutoDoorSt();
		needSend01 = 1;
	}

	//车灯状态
	if (tagCarMon.u8AutoLigSt != u8AutoLigSt())
	{
		tagCarMon.u8AutoLigSt = u8AutoLigSt();
		needSend01 = 1;
	}
	
	//附灯状态
	if (tagCarMon.u8AutoLedSt != u8AutoLedSt())
	{
		tagCarMon.u8AutoLedSt = u8AutoLedSt();
		needSend01 = 1;
	}
	
	//仪表背光亮度
	if (tagCarMon.u8BackLight != u8BackLight())
	{
		tagCarMon.u8BackLight = u8BackLight();
		needSend01 = 1;
	}
	
	//车窗状态
	if (tagCarMon.u8AutoWinSt != u8AutoWinSt())
	{
		tagCarMon.u8AutoWinSt = u8AutoWinSt();
		needSend01 = 1;
	}
	
	
	//车锁状态
	if (tagCarMon.u8AutoLockSt != u8AutoLockSt())
	{
		tagCarMon.u8AutoLockSt = u8AutoLockSt();
		needSend01 = 1;
	}
	
	//刹车和档位状态
	if (tagCarMon.u8AutoGearSt != u8AutoGearSt())
	{
		tagCarMon.u8AutoGearSt = u8AutoGearSt();
		needSend01 = 1;
	}
	
	//点火启动信号
	if (tagCarMon.u8AutoIgSt != u8AutoIgSt())
	{
		tagCarMon.u8AutoIgSt = u8AutoIgSt();
		needSend01 = 1;
	}
	
	//充电状态
	if (tagCarMon.u8ChargeSt != u8ChargeSt())
	{
		tagCarMon.u8ChargeSt = u8ChargeSt();
		needSend01 = 1;
	}
	
	//安全带状态
	if (tagCarMon.u8SaftBtSt != u8SaftBtSt())
	{
		tagCarMon.u8SaftBtSt = u8SaftBtSt();
		needSend01 = 1;
	}
	
	//里程
	if (tagCarMon.u32AutoOdo != u32AutoOdo())
	{
		tagCarMon.u32AutoOdo = u32AutoOdo();
		needSend01 = 1;
	}
	
	//油量
	if (tagCarMon.u16AutoFuel != u16AutoFuel())
	{
		tagCarMon.u16AutoFuel = u16AutoFuel();
		needSend01 = 1;
	}
	
	//电量
	if (tagCarMon.u16AutoSOC != u16AutoSOC())
	{
		tagCarMon.u16AutoSOC = u16AutoSOC();
		needSend01 = 1;
	}
	
	//续航
	if (tagCarMon.u16SocForMile != u16SocForMile())
	{
		tagCarMon.u16SocForMile = u16SocForMile();
		needSend01 = 1;
	}
	
	//车速
	if ((my_abs(tagCarMon.u16AutoSpeed, u16AutoSpeed()) > 5) ||
		( (tagCarMon.u16AutoSpeed != 0) && (u16AutoSpeed() == 0) ))
		
	{
		tagCarMon.u16AutoSpeed = u16AutoSpeed();
		needSend01 = 1;
	}
	
	//发动机转速
	if ( (my_abs(tagCarMon.u16AutoEngRd, u16AutoEngRd()) > 500) ||
		( (tagCarMon.u16AutoEngRd != 0)&&(u16AutoEngRd() == 0) ))
	{
		tagCarMon.u16AutoEngRd = u16AutoEngRd();
		needSend01 = 1;
	}

	//提醒位
	if (tagCarMon.u8AutoRemindRD != u8AutoRemindRD())
	{
		tagCarMon.u8AutoRemindRD = u8AutoRemindRD();
		needSend01 = 1;
	}
	
	//电池电压
	if (my_abs(tagCarMon.u32AutoBATVol, u32AutoBATVol()) > 1000)
	{
		tagCarMon.u32AutoBATVol = u32AutoBATVol();
		needSend01 = 1;
	}
	
	//车辆电压
	if (my_abs(tagCarMon.u32AutoVol, u32AutoVol()) > 1000)
	{
		tagCarMon.u32AutoVol = u32AutoVol();
		needSend01 = 1;
	}
	
	//油耗相关
	if (tagCarMon.u32AvgOilCsp != u32AvgOilCsp())
	{
		tagCarMon.u32AvgOilCsp = u32AvgOilCsp();
		needSend01 = 1;
	}
	//大气压力
	if (tagCarMon.u32AtmoPress != u32AtmoPress())
	{
		tagCarMon.u32AtmoPress = u32AtmoPress();
		needSend01 = 1;
	}

	//冷却液温度
	if (tagCarMon.u32CoolTemp != u32CoolTemp())
	{
		tagCarMon.u32CoolTemp = u32CoolTemp();
		needSend01 = 1;
	}
	
	//节气门位置
	if (tagCarMon.u8ThroPos != u8ThroPos())
	{
		tagCarMon.u8ThroPos = u8ThroPos();
		needSend01 = 1;
	}
	
	//方向盘转角
	if (tagCarMon.u16WheelDeg != u16WheelDeg())
	{
		tagCarMon.u16WheelDeg = u16WheelDeg();
		needSend01 = 1;
	}

	//继电器供电断电
	if (tagCarMon.RelayCtrlSta != getCurrentRelayCtrlSta())
	{
		tagCarMon.RelayCtrlSta = getCurrentRelayCtrlSta();
		needSend01 = 1;
	}
	//bit1：1 空调AC开；0关
	if (tagCarMon.air_condition != u8air_condition())
	{
		tagCarMon.air_condition = u8air_condition();
		needSend01 = 1;
	}

	//1空调风扇开；0关
	if (tagCarMon.air_fan != u8air_fan())
	{
		tagCarMon.air_fan = u8air_fan();
		needSend01 = 1;
	}
	//空调风扇档位  比如车辆有4挡，则值为0~4
	if (tagCarMon.air_fan_level != u8air_fan_level())
	{
		tagCarMon.air_fan_level = u8air_fan_level();
		needSend01 = 1;
	}
	//油门踏板开度 0~100，百分比
	if (tagCarMon.throttle_open != u8throttle_open())
	{
		tagCarMon.throttle_open = u8throttle_open();
		needSend01 = 1;
	}
	//汽车胎压
	if( tagCarMon.u32_auto_pressure != auto_tire_pressure_get() )
	{
		tagCarMon.u32_auto_pressure = auto_tire_pressure_get();
		needSend01 = 1;
	}
	//汽车胎温
	if( tagCarMon.u32_auto_temp != auto_tire_temp_get() )
	{
		tagCarMon.u32_auto_temp = auto_tire_temp_get();
		needSend01 = 1;
	}
	if (needSend01 == 0x01)
	{	/*当ACC状态处于熄火状态时，车辆状态发送改变后需要立即存储数据反正系统异常复位*/
		if ((u8AutoIgSt() & 0x08) != 0x08)
		{
			saveCarInf();
		}
		buf[0] = 0x01;
		askCarInf(buf, 1);
	}
}


uint32_t answerCarInf(void)
{
	uint16_t idx;
	uint8_t carParaLen;	//用于车身参数长度计算
	uint8_t sdata[120];
	uint32_t txlen;
	uint32_t wdata = 0;
	//Message_ID
	idx = 0;
	memcpy(&sdata[idx], "\x20\x17", 2);
	idx += 2;

	//Message_Property,afterward
	idx += 2;

	//Terminal_Num
	get_para_car_id(&sdata[idx]);
	idx += 6;

	//Message_Serial_Number
	fill_serial_num(&sdata[idx]);
	idx += 2;

	//content
	sdata[idx++] = 0x01;	//车辆状态字

	//后期写入
	carParaLen = idx;
	//sdata[idx++] = 0x00;	//状态内容长度
	//sdata[idx++] = 0x00;	
	idx +=2;
	
	
	//车门状态
	sdata[idx++] = u8AutoDoorSt();	//0
	//车灯状态
	sdata[idx++] = u8AutoLigSt();	//1
	//附灯状态
	sdata[idx++] = u8AutoLedSt();	//2
	//仪表背光亮度
	sdata[idx++] = u8BackLight();	//3
	//车窗状态
	sdata[idx++] = u8AutoWinSt();	//4
	//车锁状态
	sdata[idx++] = u8AutoLockSt();	//5
	//刹车和档位状态
	sdata[idx++] = u8AutoGearSt();	//6
	//点火启动信号
	sdata[idx++] = u8AutoIgSt();	//7
	//充电状态
	sdata[idx++] = u8ChargeSt();	//8
	//安全带状态
	sdata[idx++] = u8SaftBtSt();	//9
	//里程
	u32toHex4(u32AutoOdo(), &sdata[idx]);	//10
	idx += 4;
	//油量
	u16toHex2(u16AutoFuel(), &sdata[idx]);	//14
	idx += 2;
	//电量
	u16toHex2(u16AutoSOC(), &sdata[idx]);	//16
	idx += 2;
	//续航
	u16toHex2(u16SocForMile(), &sdata[idx]);//18
	idx += 2;
	
	//车速
	u16toHex2(u16AutoSpeed(), &sdata[idx]);	//20
	idx += 2;
	
	//发动机转速
	u16toHex2(u16AutoEngRd(), &sdata[idx]);	//22
	idx += 2;
	
	//提醒位
	sdata[idx++] = u8AutoRemindRD();		//24
	
	//电池电压
	u32toHex4(u32AutoBATVol(), &sdata[idx]);//25
	idx += 4;
	
	//车辆电压
	u32toHex4(u32AutoVol(), &sdata[idx]);	//29
	idx += 4;
	
	//油耗相关
	u32toHex4(u32AvgOilCsp(), &sdata[idx]);	//33
	idx += 4;
	
	//大气压力
	u32toHex4(u32AtmoPress(), &sdata[idx]);	//37
	idx += 4;
	
	//冷却液温度
	u32toHex4(u32CoolTemp(), &sdata[idx]);	//41
	idx += 4;
	
	//节气门位置
	sdata[idx++] = u8ThroPos();	//45
	//方向盘转角
	u16toHex2(u16WheelDeg(), &sdata[idx]);	//46
	idx += 2;
	//胎压 左前 右前 左后 右后
	wdata = ( (tagCarS.lf_TP<<24) | (tagCarS.rf_TP<<16) | (tagCarS.lr_TP<<8) | (tagCarS.rr_TP ) );	//48
	u32toHex4( wdata, &sdata[idx] );
	//u32toHex4(u32TPMSVal(), &sdata[idx]);
	idx += 4;
	//////////////////////////////////////////////////////
	//WORD 特殊状态反馈
	sdata[idx++] = 0;//高8位	//52 临时预留当作 房车项目读取黑水水位高度使用
	sdata[idx] = 0;	//低8位		//53
	
	//bit0：1时继电器供电，0时断电
	if (getCurrentRelayCtrlSta() == 1)
	{
		sdata[idx] |= 0x01;
	}
	else
	{
		sdata[idx] &= ~0x01;
	}
	
	//bit1：1 空调AC开；0关
	if (u8air_condition() == 1)
	{
		sdata[idx] |= 0x02;
	}
	else
	{
		sdata[idx] &= ~0x02;
	}
	
	//bit2：1空调风扇开；0关
	if (u8air_fan() == 1)
	{
		sdata[idx] |= 0x04;
	}
	else
	{
		sdata[idx] &= ~0x04;
	}
	
	idx++;
	//WORD 特殊状态反馈 结束
	//////////////////////////////////////////////////////
	//空调风扇档位  比如车辆有4挡，则值为0~4
	sdata[idx++] = u8air_fan_level();	//54
	//油门踏板开度 0~100，百分比
	sdata[idx++] = u8throttle_open();	//55

	/**预留的6个字节***********************************************************/
	//胎温 左前 右前 左后 右后
	wdata = ( (tagCarS.lf_T<<24) | (tagCarS.rf_T<<16) | (tagCarS.lr_T<<8) | (tagCarS.rr_T ) );
	u32toHex4( wdata, &sdata[idx] );
	idx += 4;
	sdata[idx++] = tagCarS.TPMSRst; //胎压标志是否有效
	sdata[idx++] = CAR_E_OIL;		//填充车辆类型
	// memset(&sdata[idx], 0, 6);	
	// idx += 6;
	
	//后写入车身参数长度
	sdata[carParaLen] = (idx - 2 - carParaLen) / 0x100;
	sdata[carParaLen+1] = (idx - 2 - carParaLen)%0x100;
	
	//消息体属性
	txlen = idx + 1;
	if (txlen < 13)
	{
		txlen = 13;
	}
	sdata[2] = (uint8_t)((txlen - 13) >> 8);
	sdata[3] = (uint8_t)(txlen - 13);

	//校验
	sdata[idx] = get_chk_xor(sdata, idx);
	idx++;

	format_and_send_to_mcu(sdata, idx);
	
	return 0;
}


//低于后台设置的电压后，关闭通信，进入低功耗模式
//滞回电压设置0.5V，即如果外部设定低于9V断电，需要大于9.5V才可以上电。
//每秒钟调用1次
void carVoltageMonitor(void)
{

}



//返回1低电压，返回0正常电压
uint8_t getLowPowerSta(void)
{
	return tagCarMon.LowPowerSta;
}

//返回1断电，返回0正常电压
uint8_t getPowerOffSta(void)
{
	return tagCarMon.PowerOffSta;
}


//当前设备供电电压，单位mV
//注意，这是平均值，不是当前最新值
//如果需要当前时刻最新值，需要使用getAdcVolt(4);
uint32_t getCurrentVolt(void)
{
	return tagCarMon.PowerADCAvg;
}


//增加AE- 电车数据流上传L610->GD (0x2017)
uint32_t PushDataFlowToL610(void)
{
//	uint16_t idx;
//	uint8_t sdata[MAX_SEND_L610_LEN+1];
//	uint16_t subContentLen = 0;
//	uint16_t dataTypeLen, i;
//	
//	//content
//	//类型
//	sdata[0] = 0xAE;	//车辆状态字
//	
//	//写入长度
//	dataTypeLen = sizeof(DATAFLOW);
//	subContentLen = getDataFlowLen();	//数组定义时的最大下标

//	//最后再写入长度
//	//sdata[1];
//	//sdata[2];
//	
//	sdata[3] = CAR_type_def;
//	
//	idx = 4;
//	
////	for (i=0;i<subContentLen;i++)
////	{
////		if (DataFlow[i].id != 0)
////		{
////			memcpy(&sdata[idx], &DataFlow[i], dataTypeLen);
////			idx += dataTypeLen;	//每个PID占用10字节	
////		}
////	}
//	
//	//最后写入拷贝的内容长度
//	sdata[1] = (idx-3) / 0x100;
//	sdata[2] = (idx-3) % 0x100;
//	
//	
//	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
		return 0;
	
}


//增加AF- 电车数据流上传L610->GD (0x2017 AF)
uint32_t PushDTCSaveDataToL610(void)
{
//	uint16_t idx;
//	uint8_t sdata[MAX_SEND_L610_LEN+1];
//	uint16_t subContentLen = 0;
//	uint16_t dataTypeLen, i;
//	
//	//content
//	//类型
//	sdata[0] = 0xAF;	//车辆状态字
//	
//	//写入长度
//	subContentLen = getDTCSaveDataLen();
//	dataTypeLen = sizeof(DTCSAVEDATA);
//	
//	//最后再写入长度
//	//sdata[1];
//	//sdata[2];
//	
//	sdata[3] = CAR_type_def;
//	
//	idx = 4;
//	
////	for (i=0;i<subContentLen;i++)
////	{
////		if (DTCSaveData[i].id != 0)
////		{
////			memcpy(&sdata[idx], &DTCSaveData[i], dataTypeLen);
////			idx += dataTypeLen;	//每个PID占用10字节	
////		}
////	}
//	
//	//最后写入拷贝的内容长度
//	sdata[1] = (idx-3) / 0x100;
//	sdata[2] = (idx-3) % 0x100;
//	

//	
//	return send_general_package_to_uart(0x2017, sdata, idx, 0, 0, 1);
	
		return 0;
}
/*
返回1代表有按键(检测到高电平)
返回0无按键
*/
uint8_t engine_key_rd(void)
{
	uint16_t adcDa;
	adcDa = tagCarMon.AD6 ;
	
	//5V 对应的adc为 5000*470/2470 = 951
	//3.3V 对应的adc为 3300*470/2470 = 627
	if(adcDa > 627) return 1;
	
	return 0;	
}

